package com.sinsz.c.context;

import com.google.gson.Gson;
import com.sinsz.c.context.support.LoggerData;
import com.sinsz.c.context.support.LoggerEnum;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.util.ObjectUtils;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.util.HashMap;
import java.util.Map;

/**
 * Bxfs的日志记录器
 * @author chenjianbo
 * @date 2017/11/27
 */
public class BxfsLoggerUtil {
    private BxfsLoggerUtil(){}

    private static BxfsLoggerUtil util = new BxfsLoggerUtil();

    private static Gson gson = new Gson();

    private static final Logger logger = LoggerFactory.getLogger(BxfsLoggerUtil.class);

    public static BxfsLoggerUtil instance(){
        return util;
    }

    private String http = "";

    private String filePath = "";

    private String token = "";

    private int state = 0;

    /**
     * 初始化参数
     * @param http
     * @param filePath
     */
    void init(String http, String filePath, String token) {
        if (http != null && !"".equals(http.trim())) {
            this.http = http;
            state = -1;
        }
        if (filePath != null && !"".equals(filePath.trim())) {
            this.filePath = filePath;
            state = 1;
        }
        if (token != null && !"".equals(token.trim())) {
            this.token = token;
        }
    }

    /**
     * 记录日志调用
     * @param type
     * @param host
     * @param uri
     * @param method
     * @param params
     * @param headers
     * @param errMessage
     */
    public void simpleInputLogger(
            LoggerEnum type,
            String host,
            String uri,
            String method,
            Map<String, String[]>  params,
            Map<String, String> headers,
            String errMessage) {
        LoggerData ld = new LoggerData();
        ld.setErr(errMessage == null ? "":errMessage);
        ld.setHost(host == null?"":host);
        ld.setLoggerTime(System.currentTimeMillis());
        ld.setType(type);
        ld.setUri(uri == null? "":uri);
        ld.setMethod(method == null?"":method);
        ld.setParams(ObjectUtils.isEmpty(params)?new HashMap<>(0):params);
        ld.setHeaders(ObjectUtils.isEmpty(headers)?new HashMap<>(0):headers);
        switch (state) {
            case -1:
                if (token != null && !"".equals(token.trim())) {
                    loggerPost(http, new BasicHeader("token", token), ld);
                } else {
                    loggerPost(http, null, ld);
                }
                break;
            case 1:
                String name = (type.equals(LoggerEnum.NORMAL)?"normal":"error") + ".log";
                try(BufferedWriter bw = new BufferedWriter(
                        new FileWriter(filePath + name, true)
                )) {
                    bw.write("时间：" + System.currentTimeMillis() + "  " + gson.toJson(ld));
                    bw.newLine();
                }catch (Exception e) {
                    logger.error("文件日志记录异常异常, {}", e.getLocalizedMessage());
                    e.printStackTrace(System.out);
                }
                break;
            default:
        }
    }

    /**
     * 日志服务器记录
     * @param uri
     * @param header
     * @param ld
     */
    public void loggerPost(String uri, Header header, LoggerData ld) {
        try(CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost httpPost = new HttpPost(uri);
            httpPost.addHeader("Content-Type", MediaType.APPLICATION_JSON_UTF8_VALUE);
            httpPost.setHeader("Accept", MediaType.APPLICATION_JSON_VALUE);
            if (!ObjectUtils.isEmpty(ld)) {
                StringEntity entity = new StringEntity(gson.toJson(ld), "UTF-8");
                httpPost.setEntity(entity);
            }
            if (header != null) {
                httpPost.addHeader(header);
            }
            try(CloseableHttpResponse response = httpClient.execute(httpPost)) {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("日志保存成功!");
                    }
                }
            }
        } catch (Exception e) {
            logger.error("日志服务器请求异常, {}", e.getLocalizedMessage());
            e.printStackTrace(System.out);
        }
    }

}